<template>
  <div class="publish-heatmap">
    <div class="heatmap-header">
      <h4>{{ year }}年发布活动</h4>
      <div class="stat-summary">
        <div class="stat-item">
          <span class="stat-value">{{ totalPosts }}</span>
          <span class="stat-label">总发布量</span>
        </div>
        <div class="stat-item">
          <span class="stat-value">{{ maxDay.count }}</span>
          <span class="stat-label">最高单日 ({{ formatDate(maxDay.date) }})</span>
        </div>
      </div>
    </div>
    <div class="chart-container">
      <div ref="chartContainer" class="chart"></div>
    </div>
  </div>
</template>

<script>
import * as echarts from 'echarts'
import { format } from 'date-fns'

export default {
  name: 'PublishHeatmap',
  props: {
    year: {
      type: Number,
      required: true,
    },
  },
  data() {
    return {
      chartInstance: null,
      windowResizeHandler: null,
      heatmapData: [],
      totalPosts: 0,
      maxDay: { date: new Date(), count: 0 },
    }
  },
  mounted() {
    this.initChart()
    this.updateChart()

    // 添加窗口大小变化监听器
    this.windowResizeHandler = () => {
      this.chartInstance && this.chartInstance.resize()
    }
    window.addEventListener('resize', this.windowResizeHandler)
  },
  beforeUnmount() {
    // 移除窗口大小变化监听器
    if (this.windowResizeHandler) {
      window.removeEventListener('resize', this.windowResizeHandler)
    }

    // 销毁图表实例
    if (this.chartInstance) {
      this.chartInstance.dispose()
      this.chartInstance = null
    }
  },
  watch: {
    year() {
      this.updateChart()
    },
  },
  methods: {
    /**
     * 初始化图表实例
     */
    initChart() {
      if (!this.$refs.chartContainer) return

      // 创建图表实例
      this.chartInstance = echarts.init(this.$refs.chartContainer)

      // 绑定事件监听器
      this.chartInstance.on('finished', () => {
        // 图表加载完成后触发
      })
    },

    /**
     * 更新图表数据和配置
     */
    updateChart() {
      if (!this.chartInstance) return

      // 生成模拟数据
      this.heatmapData = this.generateMockData(this.year)

      // 获取统计信息
      this.calculateStats()

      // 获取当前年份的月份名称
      const months = [
        '1月',
        '2月',
        '3月',
        '4月',
        '5月',
        '6月',
        '7月',
        '8月',
        '9月',
        '10月',
        '11月',
        '12月',
      ]

      // 获取一周的日期标签
      const days = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']

      // 图表配置选项
      const option = {
        tooltip: {
          position: 'top',
          formatter: (params) => {
            const date = new Date(params.data[0])
            const count = params.data[1]
            return `<div style="font-weight:bold;margin-bottom:4px;padding-bottom:4px;border-bottom:1px solid rgba(0,0,0,0.1);">
                      ${date.getFullYear()}年${date.getMonth() + 1}月${date.getDate()}日
                    </div>
                    <span style="display:inline-block;margin-right:5px;border-radius:50%;width:10px;height:10px;background-color:${params.color};"></span>
                    发布文章：<span style="font-weight:bold">${count}</span> 篇`
          },
          backgroundColor: 'rgba(255, 255, 255, 0.95)',
          borderColor: 'rgba(0, 0, 0, 0.1)',
          borderWidth: 1,
          padding: [10, 15],
          textStyle: {
            color: '#555',
          },
          extraCssText: 'box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1); border-radius: 8px;',
        },
        visualMap: {
          min: 0,
          max: 10,
          calculable: true,
          orient: 'horizontal',
          left: 'center',
          bottom: '0%',
          itemWidth: 12,
          itemHeight: 70,
          inRange: {
            color: [
              '#ebedf0', // 最浅色
              '#c6e48b',
              '#7bc96f',
              '#49af5d',
              '#2e8840',
              '#196127', // 最深色
            ],
          },
          text: ['高', '低'],
          textStyle: {
            color: '#666',
            fontSize: 12,
          },
        },
        calendar: {
          top: 30,
          left: 60,
          right: 20,
          bottom: 60,
          cellSize: ['auto', 15],
          range: this.year.toString(),
          itemStyle: {
            borderWidth: 1,
            borderColor: '#fff',
            borderRadius: 2,
          },
          splitLine: {
            show: true,
            lineStyle: {
              color: '#f5f5f5',
              width: 2,
              type: 'solid',
            },
          },
          dayLabel: {
            firstDay: 1, // 从周一开始
            nameMap: days,
            margin: 8,
            color: '#999',
            fontSize: 11,
            align: 'right',
          },
          monthLabel: {
            nameMap: months,
            margin: 8,
            color: '#666',
            fontSize: 12,
            fontWeight: 'bold',
          },
          yearLabel: {
            show: false,
          },
        },
        series: {
          type: 'heatmap',
          coordinateSystem: 'calendar',
          data: this.heatmapData,
          label: {
            show: false,
          },
          emphasis: {
            itemStyle: {
              shadowBlur: 10,
              shadowColor: 'rgba(0, 0, 0, 0.2)',
              borderColor: '#fff',
              borderWidth: 2,
            },
          },
        },
      }

      // 设置图表选项
      this.chartInstance.setOption(option)
    },

    /**
     * 生成模拟数据
     * @param {Number} year 年份
     * @returns {Array} 热力图数据数组
     */
    generateMockData(year) {
      const data = []
      const startDate = new Date(year, 0, 1)
      const endDate = new Date(year, 11, 31)

      for (let date = new Date(startDate); date <= endDate; date.setDate(date.getDate() + 1)) {
        const dayOfWeek = date.getDay()
        const isWeekend = dayOfWeek === 0 || dayOfWeek === 6

        // 根据一些规则生成随机数据
        let value
        const random = Math.random()

        // 周末发布概率较低
        if (isWeekend) {
          value = Math.floor(random * 3) // 0-2
        } else {
          // 周中有可能高频发布
          if (random > 0.9) {
            value = 8 + Math.floor(random * 3) // 8-10
          } else if (random > 0.7) {
            value = 4 + Math.floor(random * 4) // 4-7
          } else if (random > 0.4) {
            value = 1 + Math.floor(random * 3) // 1-3
          } else {
            value = Math.floor(random * 2) // 0-1
          }
        }

        // 一些特殊日期可能没有发布内容
        if (
          // 春节假期
          (date.getMonth() === 1 && date.getDate() >= 10 && date.getDate() <= 17) ||
          // 国庆假期
          (date.getMonth() === 9 && date.getDate() <= 7) ||
          // 随机添加一些没有发布的日期
          random < 0.2
        ) {
          value = 0
        }

        data.push([new Date(date).toISOString().split('T')[0], value])
      }

      return data
    },

    /**
     * 计算统计信息
     */
    calculateStats() {
      // 计算总发布量
      this.totalPosts = this.heatmapData.reduce((sum, item) => sum + item[1], 0)

      // 查找最高单日发布量
      let maxCount = 0
      let maxDate = new Date()

      for (const item of this.heatmapData) {
        if (item[1] > maxCount) {
          maxCount = item[1]
          maxDate = new Date(item[0])
        }
      }

      this.maxDay = {
        count: maxCount,
        date: maxDate,
      }
    },

    /**
     * 格式化日期
     */
    formatDate(date) {
      return format(date, 'MM/dd')
    },
  },
}
</script>

<style lang="scss" scoped>
.publish-heatmap {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;

  .heatmap-header {
    padding: 0 0 20px;
    display: flex;
    justify-content: space-between;
    align-items: center;

    h4 {
      font-size: 15px;
      font-weight: 500;
      color: var(--el-text-color-regular);
      margin: 0;
    }

    .stat-summary {
      display: flex;
      gap: 24px;

      .stat-item {
        display: flex;
        flex-direction: column;
        align-items: flex-end;

        .stat-value {
          font-size: 20px;
          font-weight: 600;
          color: var(--el-color-primary);
          line-height: 1;
          margin-bottom: 4px;
        }

        .stat-label {
          font-size: 13px;
          color: var(--el-text-color-secondary);
        }
      }
    }
  }

  .chart-container {
    flex: 1;
    padding: 0;
    margin: 0 -12px;

    .chart {
      width: 100%;
      height: 100%;
    }
  }
}
</style>
